package com.mrogrape.gui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JComponent;
import javax.swing.JLabel;

/**
 * 一个快速方便的用于呈现图像的组件。
 * 
 * 
 * <p>
 * <b>警告：</b>
 * <ul>
 * <li>除特殊说明，此类中所有的方法都<b>不是</b>线程安全的.
 * <li>除特殊说明，此类中所有的方法在接受null值时都会抛出NullPointerException.
 * </ul>
 * @author Ice Spring
 * @version 1.0.20110825
 */
public class PicturePane extends JComponent{

	/** SerialVersionUID */
	private static final long serialVersionUID = 6L;

	/**
	 * 保持图片原大小不变。
	 * 
	 * @see #getResizeMode()
	 * @see #setResizeMode(int)
	 */
	public static final int KEEP_SIZE = -1;

	/**
	 * 缩放图片以填充整个组件。
	 * 
	 * @see #getResizeMode()
	 * @see #setResizeMode(int)
	 */
	public static final int FILL = 1;

	/**
	 * 按比例缩放使图片宽度等于组件宽度。
	 * 
	 * @see #getResizeMode()
	 * @see #setResizeMode(int)
	 */
	public static final int FIT_WIDTH = 2;

	/**
	 * 按比例缩放使图片高度等于组件高度。
	 * 
	 * @see #getResizeMode()
	 * @see #setResizeMode(int)
	 */
	public static final int FIT_HEIGHT = 3;

	/**
	 * 对齐到顶部居中。
	 * 
	 * @see #getImageAlignment()
	 * @see #setImageAlignment(String)
	 * @see #getTitleAlignmet()
	 * @see #setTitleAlignment(String)
	 */
	public static final String NORTH = "NORTH";

	/**
	 * 对齐到右上角。
	 * 
	 * @see #getImageAlignment()
	 * @see #setImageAlignment(String)
	 * @see #getTitleAlignmet()
	 * @see #setTitleAlignment(String)
	 */
	public static final String NORTHEAST = "NORTHEAST";

	/**
	 * 对齐到右部居中。
	 * 
	 * @see #getImageAlignment()
	 * @see #setImageAlignment(String)
	 * @see #getTitleAlignmet()
	 * @see #setTitleAlignment(String)
	 */
	public static final String EAST = "EAST";

	/**
	 * 对齐到右下角。
	 * 
	 * @see #getImageAlignment()
	 * @see #setImageAlignment(String)
	 * @see #getTitleAlignmet()
	 * @see #setTitleAlignment(String)
	 */
	public static final String SOUTHEAST = "SOUTHEAST";

	/**
	 * 对齐到下部居中。
	 * 
	 * @see #getImageAlignment()
	 * @see #setImageAlignment(String)
	 * @see #getTitleAlignmet()
	 * @see #setTitleAlignment(String)
	 */
	public static final String SOUTH = "SOUTH";

	/**
	 * 对齐到左下角。
	 * 
	 * @see #getImageAlignment()
	 * @see #setImageAlignment(String)
	 * @see #getTitleAlignmet()
	 * @see #setTitleAlignment(String)
	 */
	public static final String SOUTHWEST = "SOUTHWEST";

	/**
	 * 对齐到左部居中。
	 * 
	 * @see #getImageAlignment()
	 * @see #setImageAlignment(String)
	 * @see #getTitleAlignmet()
	 * @see #setTitleAlignment(String)
	 */
	public static final String WEST = "WEST";

	/**
	 * 对齐到左上角。
	 * 
	 * @see #getImageAlignment()
	 * @see #setImageAlignment(String)
	 * @see #getTitleAlignmet()
	 * @see #setTitleAlignment(String)
	 */
	public static final String NORTHWEST = "NORTHWEST";

	/**
	 * 对齐到正中央。
	 * 
	 * @see #getImageAlignment()
	 * @see #setImageAlignment(String)
	 * @see #getTitleAlignmet()
	 * @see #setTitleAlignment(String)
	 */
	public static final String CENTER = "CENTER";


	/**
	 * 创建默认的PicturePane。
	 */
	public PicturePane() {
		this(null, -1, PicturePane.NORTHWEST);
	}

	/**
	 * 创建PicturePane并指定要显示的图片。
	 * 
	 * @param image 要显示的图片。
	 * @see #getImage()
	 */
	public PicturePane(Image image) {

		this(image, -1, PicturePane.NORTHWEST);
	}

	/**
	 * 创建PicturePane并指定要显示的图片和图片的缩放模式。
	 * 
	 * @param image 要显示的图片。
	 * @param resizeMode 图片的缩放模式。
	 * @see #getImage()
	 * @see #getResizeMode()
	 */
	public PicturePane(Image image,int resizeMode) {

		this(image, resizeMode, PicturePane.NORTHWEST);
	}

	/**
	 * 创建PicturePane并指定要显示的图片和图片的缩放模式以及对齐方式。
	 * 
	 * @param image 要显示的图片。
	 * @param displayMode 图片的缩放模式。
	 * @param imageAlign 图片的对齐方式。
	 * @see #getImage()
	 * @see #getResizeMode()
	 * @see #getImageAlignment()
	 */
	public PicturePane(Image image, int displayMode, String imageAlign) {

		if(imageAlign == null){
			throw new NullPointerException("ImageAlign can not be null.");
		}

		this.image = image;
		this.resizeMode = displayMode;
		this.imageAlignment = imageAlign;

		this.refreshPreferredSize();

	}

	/**
	 * 从文件读取一个图片文件并显示。
	 * 
	 * <p>
	 * 支持GIF,PNG,JPG,JPEG,BMP,WBMP格式文件的读取。
	 * 
	 * <p>
	 * <b>注意：</b>尽管此类中的大部分方法不是线程安全的，但此方法是<b>线程安全</b>的。
	 * 
	 * @param file 图片文件。
	 * @throws IOException 读取文件时发生IO异常。
	 */
	public synchronized void loadImage(final File imageFile) throws IOException{

		if(imageFile == null){
			throw new NullPointerException("imageFile can not be empty");
		}

		if (imageFile.getName().toLowerCase().endsWith("png")) {
			final Image image = ImageIO.read(imageFile);
			EventQueue.invokeLater(new Runnable() {
				@Override
				public void run() {

					PicturePane.this.setImage(image);
				}
			});
		}

		final Image image = Toolkit.getDefaultToolkit().createImage(
				imageFile.toString());
		EventQueue.invokeLater(new Runnable() {
			@Override
			public void run() {

				PicturePane.this.setImage(image);
			}
		});



	}

	/**
	 * 获取调整图片的缩放模式。
	 * 
	 * <p>
	 * 这个值描述了当组件大小和图片大小不相符时使用的缩放模式，默认情况下使用KEEP_SIZE.
	 * 
	 * <p>
	 * 此类提供了以下模式几种模式：
	 * <ul>
	 * <li>PicturePane.KEEP_SIZE  : 保持图片原大小。
	 * <li>PicturePane.FILL       : 拉伸以填充整个组件。
	 * <li>PicturePane.FIT_WIDTH  : 按比例缩放使图片宽度等于组件宽度。
	 * <li>PicturePane.FIT_HEIGHT : 按比例缩放使图片高度等于组件高度。
	 * </ul>
	 * 
	 * @return 调整图片大小时使用的模式。
	 * @see #setResizeMode(int)
	 */
	public int getResizeMode() {

		return this.resizeMode;
	}

	/**
	 * 设置调整图片大小时使用的模式。
	 * 
	 * @param resizeMode 调整图片大小时使用的模式。
	 * @see #getResizeMode()
	 */
	public void setResizeMode(int resizeMode) {

		if (resizeMode != PicturePane.FILL && resizeMode != PicturePane.KEEP_SIZE
				&& resizeMode != PicturePane.FIT_WIDTH && resizeMode != PicturePane.FIT_HEIGHT) {

			throw new IllegalArgumentException("Bad Mode.");
		}

		int oldValue = this.resizeMode;

		this.resizeMode = resizeMode;
		this.repaint();

		this.firePropertyChange("resizeMode", oldValue, resizeMode);
	}

	/**
	 * 获取图片的对齐方式。
	 * 
	 * <p>
	 * 这个值描述了当图片无法填充至整个组件时，图片在组件中的对齐策略。采用方位名称来
	 * 形容。当采用FILL模式时这个值没有任何意义，以为这种模式不会出现空白。
	 * 
	 * @return 图片的对齐方式。
	 * @see #setResizeMode(int)
	 */
	public String getImageAlignment() {

		return this.imageAlignment;
	}

	/**
	 * 设置图片对齐方式。
	 * 
	 * <p>
	 * 采用方位名词的英文（东，南，西....）描述。本类也提供了常量。
	 * 
	 * @param imageAlignment 对齐方式。
	 * @see #getImageAlignment()
	 */
	public void setImageAlignment(String imageAlignment) {

		if(imageAlignment == null){
			throw new NullPointerException("imageAlignment can not be null.");
		}

		String oldValue = this.imageAlignment;

		this.imageAlignment = imageAlignment;
		this.repaint();

		this.firePropertyChange("imageAlignment", oldValue, this.imageAlignment);
	}

	/**
	 * 查看是否显示图片标题。
	 * 
	 * <p>
	 * <b>注意：</b>如果没有设置要显示的图片或者将图片设置为空，则标题也不会显示。
	 * 
	 * @return 是否显示图片标题。true:显示；false:不显示。
	 * @see #setShowImageTitle(boolean)
	 */
	public boolean isShowImageTitle() {

		return this.isShowImageTitle;
	}

	/**
	 * 设置是否显示图片标题。
	 * 
	 * @param isShowImageTitle 是否显示图片标题。true:显示；false:不显示。
	 * @see #isShowImageTitle()
	 */
	public void setShowImageTitle(boolean isShowImageTitle) {

		boolean old = this.isShowImageTitle;

		this.isShowImageTitle = isShowImageTitle;
		this.repaint();

		this.firePropertyChange("showImageTitle", old, this.isShowImageTitle);
	}

	/**
	 * 获取在此PicturePane要显示的图片，如果没有，则为null.
	 * 
	 * @return 获取在此PicturePane要显示的图片，如果没有，则为null.
	 * @see #setImage(Image)
	 */
	public Image getImage() {

		return this.image;
	}

	/**
	 * 设置要在此Picture上显示的图片，可以为null。
	 * 
	 * 
	 * @param image 要在此Picture上显示的图片，可以为null。
	 * @see #getImage()
	 */
	public void setImage(Image image) {

		Image old = this.image;

		this.image = image;
		this.refreshPreferredSize();
		this.repaint();

		this.firePropertyChange("image", old, this.image);
	}

	/**
	 * 获取当没有图片需要显示时，此PicturePane显示的默认图片，这个值可能为null。
	 * 
	 * @return 当没有图片需要显示时，此PicturePane显示的默认图片，这个值可能为null。
	 * @see #setDefaultImage(Image)
	 */
	public Image getDefaultImage() {

		return this.defaultImage;
	}

	/**
	 * 设置当没有图片需要显示时，此PicturePane显示的默认图片，这个值可以为null。
	 * 
	 * @param defaultImage 当没有图片需要显示时，此PicturePane显示的默认图片，这个值可以为null。
	 * @see #getDefaultImage()
	 */
	public void setDefaultImage(Image defaultImage) {

		Image old = this.defaultImage;

		this.defaultImage = defaultImage;
		this.repaint();

		this.firePropertyChange("defaultImage", old, this.defaultImage);
	}

	/**
	 * 获取当没有任何图片可以显示时，显示的提示文本。
	 * 
	 * @return 当没有任何图片可以显示时，显示的提示文本。
	 * @see #setInfoWhenNoImage(String)
	 */
	public String getInfoWhenNoImage() {

		return this.infoWhenNoImage;
	}

	/**
	 * 设置当没有任何图片可以显示时，显示的提示文本。
	 * 
	 * @param infoWhenNoImage 当没有任何图片可以显示时，显示的提示文本。
	 * @see #getInfoWhenNoImage()
	 */
	public void setInfoWhenNoImage(String infoWhenNoImage) {

		if(infoWhenNoImage == null){
			throw new NullPointerException("infoWhenNoImage can not be null.");
		}

		String old = this.infoWhenNoImage;

		this.infoWhenNoImage = infoWhenNoImage;
		this.repaint();

		this.firePropertyChange("infoWhenNoImage", old, this.infoWhenNoImage);
	}

	/**
	 * 获取图片标题。
	 * 
	 * @return 图片标题。
	 * @see #setTitle(String)
	 */
	public String getTitle() {

		return this.title;
	}

	/**
	 * 设置图片标题。
	 * 
	 * @param title 图片标题。
	 * @see #getTitleColor()
	 */
	public void setTitle(String title) {

		if(title == null){
			throw new NullPointerException("title can not be null.");
		}

		String old = this.title;

		this.title = title;
		this.repaint();

		this.firePropertyChange("title", old, this.title);
	}

	/**
	 * 获取图片标题对齐方式。
	 * 
	 * <p>
	 * 这个值显示了图片标题显示在组件上的位置。采用方位名词描述。
	 * 
	 * @return 图片标题对齐方式。
	 * @see #getImageAlignment()
	 * @see #setTitleAlignment(String)
	 */
	public String getTitleAlignmet() {

		return this.titleAlign;
	}

	/**
	 * 设置图片标题对齐方式。
	 * 
	 * @param titleAlign 图片标题对齐方式。
	 * @see #getTitleAlignmet()
	 */
	public void setTitleAlignment(String titleAlign) {

		if(titleAlign == null){
			throw new NullPointerException("titleAlign can not be null.");
		}

		String old = this.titleAlign;

		this.titleAlign = titleAlign;
		this.repaint();

		this.firePropertyChange("titleAlignment", old,this.titleAlign);
	}

	/**
	 * 获取标题与组件边界的余白（如果可能）。
	 * 
	 * <p>
	 * 此方法受标题的对齐方式影响，在同一时刻最多有两个值有效。如当对齐方式是EAST时
	 * 只有insets.right值是有意义的。
	 * 
	 * @return 标题与组件边界的余白（如果可能）。
	 * @see #setTitleMargin(Insets)
	 */
	public Insets getTitleMargin() {

		return this.titleMargin;
	}

	/**
	 * 设置标题与组件边界的余白（如果可能）。
	 * 
	 *  <p>
	 * 此方法受标题的对齐方式影响，在同一时刻最多有两个值有效。如当对齐方式是EAST时
	 * 只有insets.right值是有意义的。
	 * 
	 * @param titleMargin 标题与组件边界的余白（如果可能）。
	 */
	public void setTitleMargin(Insets titleMargin) {

		if(titleMargin == null){
			throw new NullPointerException("titleMargin can not be null.");
		}

		Insets old = this.titleMargin;

		this.titleMargin = titleMargin;
		this.repaint();

		this.firePropertyChange("titleMargin", old, this.titleMargin);
	}

	/**
	 * 获取呈现图片标题时使用的颜色。
	 * 
	 * @return 呈现图片标题时使用的颜色。
	 * @see #setTitleColor(Color)
	 */
	public Color getTitleColor() {

		return this.titleColor;
	}

	/**
	 * 设置呈现图片标题时使用的颜色。
	 * 
	 * @param titleColor 呈现图片标题时使用的颜色。
	 * @see #getTitleColor()
	 */
	public void setTitleColor(Color titleColor) {

		if(titleColor == null){
			throw new NullPointerException("titileColor can not be null.");
		}

		Color old = this.titleColor;

		this.titleColor = titleColor;
		this.repaint();

		this.firePropertyChange("titleColor", old, this.titleColor);
	}

	/**
	 * 获取呈现图片标题时使用的字体。
	 * 
	 * @return 呈现图片标题时使用的字体。
	 * @see #setTitleFont(Font)
	 */
	public Font getTitleFont() {

		return this.titleFont;
	}

	/**
	 * 设置呈现图片标题时使用的字体。
	 * 
	 * @param titleFont 呈现图片标题时使用的字体。
	 * @see #getTitleFont()
	 */
	public void setTitleFont(Font titleFont) {

		if(titleFont == null){
			throw new NullPointerException("titleFont can not be null.");
		}

		Font old = this.titleFont;

		this.titleFont = titleFont;
		this.repaint();

		this.firePropertyChange("titleFont", old, this.titleFont);
	}

	@Override
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);

		Graphics2D g2d = (Graphics2D)g;
		FontRenderContext fontRenderContext = g2d.getFontRenderContext();
		int width = this.getWidth();
		int height = this.getHeight();

		Image image = this.getDisplayImage();

		// Draw the info when image not exist.
		if(image == null){
			Rectangle2D rec = this.getFont().getStringBounds(this.infoWhenNoImage, fontRenderContext);
			Point location = this.getCenterOrigin((int)rec.getWidth(),(int)rec.getHeight());

			g2d.drawString(this.infoWhenNoImage, location.x, location.y);
			return;
		}

		// Draw the picture.

		int imageWidth = image.getWidth(this);
		int imageHeight = image.getHeight(this);

		// File Mode
		if(this.resizeMode == PicturePane.FILL){

			g2d.drawImage(image, 0, 0, width, height, this);
		} 
		// Fit the component width mode
		else if(this.resizeMode == PicturePane.FIT_WIDTH){

			float rate = (float)width/(float)imageWidth;
			int fixedHeight = (int)(imageHeight*rate);

			if (this.imageAlignment.equalsIgnoreCase(PicturePane.NORTH)
					|| this.imageAlignment.equalsIgnoreCase(PicturePane.NORTHEAST)
					|| this.imageAlignment.equalsIgnoreCase(PicturePane.NORTHWEST)) {

				g2d.drawImage(image, 0, 0, width, fixedHeight,this);

			} else if (this.imageAlignment.equalsIgnoreCase(PicturePane.EAST)
					|| this.imageAlignment.equalsIgnoreCase(PicturePane.CENTER)
					|| this.imageAlignment.equalsIgnoreCase(PicturePane.WEST)) {

				int y = (height - fixedHeight)/2;

				g2d.drawImage(image, 0, y, width, fixedHeight,this);

			} else if (this.imageAlignment.equalsIgnoreCase(PicturePane.SOUTH)
					|| this.imageAlignment.equalsIgnoreCase(PicturePane.SOUTHEAST)
					|| this.imageAlignment.equalsIgnoreCase(PicturePane.SOUTHWEST)) {

				int y = height - fixedHeight;
				g2d.drawImage(image, 0, y, width, fixedHeight,this);
			}

		} 
		// Fit the component height mode.
		else if(this.resizeMode == PicturePane.FIT_HEIGHT){

			float rate = (float)height/(float)imageHeight;
			int fixedWidth = (int) (imageWidth * rate);

			if (this.imageAlignment.equalsIgnoreCase(PicturePane.WEST)
					|| this.imageAlignment.equalsIgnoreCase(PicturePane.SOUTHWEST)
					|| this.imageAlignment.equalsIgnoreCase(PicturePane.NORTHWEST)) {

				g2d.drawImage(image, 0, 0, fixedWidth, height, this);
			} else if (this.imageAlignment.equalsIgnoreCase(PicturePane.NORTH)
					|| this.imageAlignment.equalsIgnoreCase(PicturePane.CENTER)
					|| this.imageAlignment.equalsIgnoreCase(PicturePane.SOUTH)) {

				int x = (width - fixedWidth) / 2;

				g2d.drawImage(image, x, 0, fixedWidth, height, this);

			} else if (this.imageAlignment.equalsIgnoreCase(PicturePane.EAST)
					|| this.imageAlignment.equalsIgnoreCase(PicturePane.NORTHEAST)
					|| this.imageAlignment.equalsIgnoreCase(PicturePane.SOUTHEAST)) {

				int x = width - fixedWidth;

				g2d.drawImage(image, x, 0, fixedWidth, height, this);
			}

		} 
		// Keep the image size mode.
		else if(this.resizeMode == PicturePane.KEEP_SIZE){

			int x = 0;
			int y = 0;

			if(this.imageAlignment.equalsIgnoreCase(PicturePane.NORTH)){

				x = (width - imageWidth)/2;

			} else if(this.imageAlignment.equalsIgnoreCase(PicturePane.NORTHEAST)){

				x = width - imageWidth;

			} else if(this.imageAlignment.equalsIgnoreCase(PicturePane.EAST)){

				x = width - imageWidth;
				y = (height - imageHeight)/2;

			} else if(this.imageAlignment.equalsIgnoreCase(PicturePane.SOUTHEAST)){

				x = width - imageWidth;
				y = height - imageHeight;

			} else if(this.imageAlignment.equalsIgnoreCase(PicturePane.SOUTH)){

				x = (width - imageWidth)/2;
				y = height - imageHeight;

			} else if(this.imageAlignment.equalsIgnoreCase(PicturePane.SOUTHWEST)){

				y = height - imageHeight;

			} else if(this.imageAlignment.equalsIgnoreCase(PicturePane.WEST)){

				y = (height - imageHeight)/2;

			} else if(this.imageAlignment.equalsIgnoreCase(PicturePane.CENTER)){

				x = (width - imageWidth)/2;
				y = (height - imageHeight)/2;
			}

			g2d.drawImage(image, x, y, imageWidth, imageHeight, this);

		}

		//Draw the title

		if((this.title == null && this.title.isEmpty())||this.image == null){
			return;
		}

		if(!this.isShowImageTitle){
			return;
		}

		g2d.setFont(this.titleFont);
		g2d.setColor(this.titleColor);

		Rectangle2D trd = this.titleFont.getStringBounds(this.title, fontRenderContext);
		int tw = (int) trd.getWidth();
		int th = (int) trd.getHeight();

		int tx = 0;
		int ty = 0;

		if(this.titleAlign.equalsIgnoreCase(PicturePane.NORTHWEST)){

			tx = this.titleMargin.left;
			ty = this.titleMargin.top;

		} else if(this.titleAlign.equalsIgnoreCase(PicturePane.NORTH)){

			tx = (width - tw)/2;
			ty = this.titleMargin.top;

		} else if(this.titleAlign.equalsIgnoreCase(PicturePane.NORTHEAST)){

			tx = width - tw - this.titleMargin.right;
			ty = this.titleMargin.top;

		} else if(this.titleAlign.equalsIgnoreCase(PicturePane.EAST)){

			tx = width - tw - this.titleMargin.right;
			ty = (height - th)/2;

		} else if(this.titleAlign.equalsIgnoreCase(PicturePane.SOUTHEAST)){

			tx = width - tw - this.titleMargin.right;
			ty = height - th - this.titleMargin.bottom;

		} else if(this.titleAlign.equalsIgnoreCase(PicturePane.SOUTH)){

			tx = (width - tw)/2;
			ty = height - th - this.titleMargin.bottom;

		} else if(this.titleAlign.equalsIgnoreCase(PicturePane.SOUTHWEST)){

			tx = this.titleMargin.left;
			ty = height - th - this.titleMargin.bottom;

		} else if(this.titleAlign.equalsIgnoreCase(PicturePane.WEST)){

			tx = this.titleMargin.left;
			ty = (height - th)/2;

		} else if(this.titleAlign.equalsIgnoreCase(PicturePane.CENTER)){

			tx = (width - tw)/2;
			ty = (height - th)/2;
		}

		g2d.drawString(this.title, tx, ty);

	}

	/**
	 * 获取现在需要显示的图片。
	 * 
	 * <p>当用户设定了此ImageViewer显示的图片或其不为null时返回用户设定的Image，否则
	 * 返回默认显示Image.
	 * 
	 * @return 现在需要显示的图片。
	 */
	private Image getDisplayImage(){
		if(this.image != null){
			return this.image;
		}

		return this.defaultImage;
	}

	/**
	 * 计算一个矩形组件需居中显示时其绘图原点。
	 * 
	 * @param width 矩形组件的宽。
	 * @param height 矩形组件的长。
	 * @return 矩形组件居中显示时的绘图原点。
	 */
	private Point getCenterOrigin(int width,int height){
		Point re = new Point();

		int x = (this.getWidth() - width)/2;
		int y = (this.getHeight() - height)/2;

		re.setLocation(x, y);

		return re;
	}

	/**
	 * 刷新组件首选大小。
	 * 
	 */
	private void refreshPreferredSize(){

		if(this.image == null){
			return;
		}

		int pw = this.image.getWidth(this);
		int ph = this.image.getHeight(this);

		if(pw > 0 && ph > 0){
			this.setPreferredSize(new Dimension(pw,ph));
		}
	}


	private int resizeMode = -1;
	private String imageAlignment = PicturePane.NORTHWEST;
	private boolean isShowImageTitle = false;

	private Image image = null;
	private Image defaultImage = null;
	private String infoWhenNoImage = "No Image";

	private String title = "No Titile";
	private String titleAlign = PicturePane.NORTHWEST;
	private Insets titleMargin = new Insets(10,10,10,10);
	private Color titleColor = Color.BLACK;
	private Font titleFont = new JLabel().getFont();
}
